import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'
import { isDate, isObject, snakeCase } from 'lodash'
import { Observable, map } from 'rxjs'

@Injectable()
export class ResponseParameterSerializeInterceptor implements NestInterceptor {
  static readonly IGNORES = new WeakMap<Object, Array<string | symbol>>()

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    if (ResponseParameterSerializeInterceptor.IGNORES.get(context.getClass())?.includes(context.getHandler().name)) {
      return next.handle()
    }

    return next.handle().pipe(map(transformResponseData))
  }
}

/**
 * 处理响应数据格式
 * @param data
 * @returns
 */
function transformResponseData(data: any) {
  if (data == null) {
    return data
  }

  // 数组循环处理
  if (Array.isArray(data)) {
    return data.map(transformResponseData)
  }

  // 日期类型转为时间戳
  if (isDate(data)) {
    return data.getTime()
  }

  if (isObject(data)) {
    const newData: any = {}
    Object.keys(data).forEach(key => {
      // key转下划线格式
      newData[snakeCase(key)] = transformResponseData(data[key])
    })
    return newData
  }

  return data
}
